﻿namespace SampleDdeCustomTable
{
	using System;
	using System.ComponentModel;
	using System.Linq;
	using System.Windows;
	using System.Windows.Forms;
	using MessageBox = System.Windows.MessageBox;

	using Ecng.Collections;
	using Ecng.Common;
	using Ecng.Xaml;

	using StockSharp.Quik;

    using StockSharp.BusinessEntities;

    using System.Threading;
    
    using System.Data;

    using FuncCandels;
    using FuncSystem;

	public partial class MainWindow
	{
        private static Security  _sec2;
        //private static Portfolio _portfolio;
        private static MarketDepth _depth2;

		public QuikTrader Trader;

		private readonly CandlesWindow _candlesWindow = new CandlesWindow();
		private DdeCustomTable _table;
        private MySql.Data.MySqlClient.MySqlConnection conn;
        private MySql.Data.MySqlClient.MySqlCommand cmd;

		public MainWindow()
		{
            // запускать только в рабочее время
            //if ((int)DateTime.Now.DayOfWeek > 5) return;

			InitializeComponent();
			MainWindow.Instance = this;
			_candlesWindow.MakeHideable();

			// попробовать сразу найти месторасположение Quik по запущенному процессу
			this.Path.Text = QuikTerminal.GetDefaultPath();

            MySQLConnect();
            cmd.CommandText = "TRUNCATE TABLE history_quik_temp";
            cmd.ExecuteNonQuery();

            MyConnect();



            MyExportDde();


            stakan("SRH2");
            StartDde();            
            
            
           // stakan("SRH2");
            //stakan2();
            
            
            MyShowCandles();
            
            
		}

		protected override void OnClosing(CancelEventArgs e)
		{
			_candlesWindow.DeleteHideable();
			_candlesWindow.Close();

			if (this.Trader != null)
			{
				if (_isDdeStarted)
					StopDde();

				this.Trader.Dispose();
			}

			base.OnClosing(e);
		}

		public static MainWindow Instance { get; private set; }

        private void MySQLConnect()
        {

           
            //MySql.Data.MySqlClient.MySqlDataAdapter myAdapter;

            conn = new MySql.Data.MySqlClient.MySqlConnection();
            cmd = new MySql.Data.MySqlClient.MySqlCommand();
            //myAdapter = new MySql.Data.MySqlClient.MySqlDataAdapter();

            //conn.ConnectionString = "server=92.255.251.110;uid=ast;pwd=7hxSAYcrYCjn7nb5;database=pager;";
            conn.ConnectionString = "server=localhost;uid=ast;pwd=7hxSAYcrYCjn7nb5;database=pager;";
            conn.Open();
            cmd.Connection = conn;
        }
        //private void MySQLInsert(string seccode, string per, string date, string time, string open, string high, string low, string close, string vol, string macd, string macdg, string macds)
        //    {
        //        cmd.CommandText = "INSERT INTO `history_quik_temp` (`seccode`,`per`,`date`,`time`,`open`,`high`,`low`,`close`,`vol`,`macd`,`macdg`,`macds`) VALUES ('"
        //                                    + seccode + "','" + per + "','"+ date + "','"+ time + "','"+ open + "','"+ high + "','"+ low + "','"+ close + "','"+ vol + "','"+ macd + "','"+ macdg + "','"+ macdg 
        //                   + "')";
        //        cmd.ExecuteNonQuery();

        //}

		private void FindPath_Click(object sender, RoutedEventArgs e)
		{
			var dlg = new FolderBrowserDialog();

			if (!this.Path.Text.IsEmpty())
				dlg.SelectedPath = this.Path.Text;

			if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
			{
				this.Path.Text = dlg.SelectedPath;
			}
		}

		private bool _isConnected;

        private void MyConnect()
        {
            

            if (!_isConnected)
            {
                if (this.Path.Text.IsEmpty())
                    MessageBox.Show(this, "Путь к Quik не выбран");
                else
                {
                    if (this.Trader == null)
                    {
                        // создаем шлюз
                        this.Trader = new QuikTrader(this.Path.Text);

                        // возводим флаг, что соединение установлено
                        _isConnected = true;

                        // подписываемся на событие ошибки соединения
                       // this.Trader.ConnectionError += error => this.GuiAsync(() => MessageBox.Show(this, error.ToString()));

                        // добавляем тип QuikCandle для преобразования строчки из таблица Исторические свечи в объект QuikCandle
                        _table = new DdeCustomTable(typeof(QuikCandle));
                        this.Trader.CustomTables.Add(_table);

                        //this.Trader.NewCustomTables += (type, objects) =>
                        //{
                        //    // нас интересует только QuikCandle
                        //    if (type == typeof(QuikCandle))
                        //    {
                        //        _candlesWindow.Candles.AddRange(objects.Cast<QuikCandle>());
                        //        var candles = objects.Cast<QuikCandle>();
                        //        string messag;
                        //        foreach (var candle in candles) // перебор свечек 
                        //        {
                        //            messag = System.Convert.ToString(candle.OpenPrice) + System.Convert.ToString(candle.SecCode);
                        //        }
                        //    }
                        //};

                        this.Trader.NewCustomTables += (type, objects) =>
                        {
                            // нас интересует только QuikCandle
                            if (type == typeof(QuikCandle))
                            {
                                 _candlesWindow.Candles.AddRange(objects.Cast<QuikCandle>());
                                var candles = objects.Cast<QuikCandle>();
                                string seccode, seccode_trans, per, date, time, open, high, low, close, vol, macd, macdg, macds, elder, tenkan, kijun, senkou_span1, senkou_span2,chinkou;
                                string messag;
                                foreach (var candle in candles) // перебор свечек 
                                {
                                    messag = System.Convert.ToString(candle.OpenPrice) + System.Convert.ToString(candle.SecCode);
                                    //MySQLConnect2();
                                    seccode = Convert.ToString(candle.SecCode);
                                    seccode_trans = Convert.ToString(candle.seccode_trans);
                                    per = Convert.ToString(candle.per);
                                    date = Convert.ToString(candle.date);
                                    time = Convert.ToString(candle.time);
                                    open = Convert.ToString(candle.OpenPrice).Replace(',', '.');
                                    high = Convert.ToString(candle.HighPrice).Replace(',', '.');
                                    low = Convert.ToString(candle.LowPrice).Replace(',', '.');
                                    close = Convert.ToString(candle.ClosePrice).Replace(',', '.');
                                    vol = Convert.ToString(candle.Volume);
                                    macd = Convert.ToString(candle.MACD).Replace(',', '.');
                                    macdg = Convert.ToString(candle.MACDG).Replace(',', '.');
                                    macds = Convert.ToString(candle.MACDS).Replace(',', '.');
                                    elder = Convert.ToString(candle.elder).Replace(',', '.');
                                    tenkan = Convert.ToString(candle.tenkan).Replace(',', '.');
                                    kijun = Convert.ToString(candle.kijun).Replace(',', '.');
                                    senkou_span1 = Convert.ToString(candle.senkou_span1).Replace(',', '.');
                                    senkou_span2 = Convert.ToString(candle.senkou_span2).Replace(',', '.');
                                    chinkou = Convert.ToString(candle.chinkou).Replace(',', '.');



                                    cmd.CommandText = "INSERT INTO `history_quik_temp` (`seccode`,`seccode_trans`,`per`,`date`,`time`,`open`,`high`,`low`,`close`,`vol`,`macd`,`macdg`,`macds`, `elder`, `tenkan`, `kijun`, `senkou_span1`, `senkou_span2`,`chinkou`) VALUES ('"
                                           + seccode + "','"
                                           + seccode_trans + "','" 
                                           + per + "','" 
                                           + date + "','" 
                                           + time + "','" 
                                           + open + "','" 
                                           + high + "','" 
                                           + low + "','" 
                                           + close + "','" 
                                           + vol + "','" 
                                           + macd + "','"
                                           + macdg + "','" 
                                           + macds + "','"
                                           + elder + "','"
                                           + tenkan + "','"
                                           + kijun + "','"
                                           + senkou_span1 + "','"
                                           + senkou_span2 + "','"
                                           + chinkou
                                           + "')";
                                    cmd.ExecuteNonQuery();


                                   // MySQLInsert(seccode, per, date, time, open, high, low, close, vol, macd, macdg, macds);
                                    //MessageBox.Show(messag);//mscandle.OpenPrice - цена открытия свечки 
                                }
                                Data.combine();
                            }
                        };

                        this.Trader.Connected += () => this.GuiAsync(() =>
                        {
                            this.ShowCandles.IsEnabled = true;
                            this.ExportDde.IsEnabled = true;

                            _isConnected = true;
                            this.ConnectBtn.Content = "Отключиться";
                        });

                        this.Trader.Disconnected += () => this.GuiAsync(() =>
                        {
                            _isConnected = false;
                            this.ConnectBtn.Content = "Подключиться";
                        });
                    }

                    this.Trader.Connect();
                }
            }
            else
                this.Trader.Disconnect();
        }

		private void Connect_Click(object sender, RoutedEventArgs e)
		{
			if (!_isConnected)
			{
				if (this.Path.Text.IsEmpty())
					MessageBox.Show(this, "Путь к Quik не выбран");
				else
				{
					if (this.Trader == null)
					{
						// создаем шлюз
						this.Trader = new QuikTrader(this.Path.Text);

						// возводим флаг, что соединение установлено
						_isConnected = true;



                        //// подписываемся на событие появления моих новых сделок
                        //trader.NewMyTrades += myTrades =>
                        //{
                        //    foreach (var myTrade in myTrades)
                        //    {
                        //        var trade = myTrade.Trade;
                        //        Console.WriteLine("Сделка {0} по цене {1} по бумаге {2} по объему {3} в {4}.", trade.Id, trade.Price, trade.Security.Code, trade.Volume, trade.Time);
                        //    }
                        //};


						// подписываемся на событие ошибки соединения
						this.Trader.ConnectionError += error => this.GuiAsync(() => MessageBox.Show(this, error.ToString()));

						// добавляем тип QuikCandle для преобразования строчки из таблица Исторические свечи в объект QuikCandle
						_table = new DdeCustomTable(typeof(QuikCandle));
						this.Trader.CustomTables.Add(_table);

						this.Trader.NewCustomTables += (type, objects) =>
						{
							// нас интересует только QuikCandle
                            if (type == typeof(QuikCandle))
                                _candlesWindow.Candles.AddRange(objects.Cast<QuikCandle>());
						};

						this.Trader.Connected += () => this.GuiAsync(() =>
						{
							this.ShowCandles.IsEnabled = true;
							this.ExportDde.IsEnabled = true;

							_isConnected = true;
							this.ConnectBtn.Content = "Отключиться";
						});

						this.Trader.Disconnected += () => this.GuiAsync(() =>
						{
							_isConnected = false;
							this.ConnectBtn.Content = "Подключиться";
						});
					}
					
					this.Trader.Connect();
				}
			}
			else
				this.Trader.Disconnect();
		}
        
        private void MyShowCandles()
        {
            ShowOrHide(_candlesWindow);
        }

		private void ShowCandles_Click(object sender, RoutedEventArgs e)
		{
			ShowOrHide(_candlesWindow);
		}

		private static void ShowOrHide(Window window)
		{
			if (window == null)
				throw new ArgumentNullException("window");
			if (window.Visibility == Visibility.Visible)
				window.Hide();
			else
				window.Show();
		}

		private bool _isDdeStarted;

		private void StartDde()
		{
            
            //this.Trader.StartExport(Trader.SecuritiesTable);
            this.Trader.StartExport(_table);

           // this.Trader.StartExport(this.Trader.SecuritiesTable, this.Trader.MyTradesTable, this.Trader.EquityPositionsTable,
             //                        this.Trader.EquityPortfoliosTable, this.Trader.OrdersTable);
			_isDdeStarted = true;
		}

		private void StopDde()
		{
            this.Trader.StopExport(_table);
			_isDdeStarted = false;
		}

        private void MyExportDde()
        {
            if (_isDdeStarted)
                StopDde();
            else
                StartDde();
        }
		private void ExportDde_Click(object sender, RoutedEventArgs e)
		{
			if (_isDdeStarted)
				StopDde();
			else
				StartDde();
		}

        private void stakan(string secCode)
        {
            //  Security _sec2 = null;
             // MarketDepth _depth2 = null;
         //   {
                //if () {
                // для теста выбираем бумагу Лукойл
                //string secCode1 = "LKZ1";
                //int Vol1 = 99;

                //string secCode = "SRZ1";
                //int VolsecCode = 2500;

                secCode = "SRH2";
                int VolsecCode = 2500;

                
                // подписываемся на событие появление инструментов


                this.Trader.NewSecurities += securities =>
                {
                    if (_sec2 == null)
                    {
                        //if (_sec1 == null) _sec1 = securities.FirstOrDefault(sec => sec.Code == secCode1);
                        if (_sec2 == null) _sec2 = securities.FirstOrDefault(sec => sec.Code == secCode);

                        //if (_sec1 != null) trader.RegisterQuotes(_sec1);// запускаем экспорт стакана      
                        if (_sec2 != null) this.Trader.RegisterQuotes(_sec2);// запускаем экспорт стакана
                    }
                };




                // подписываемся на событие обновления стакана
                this.Trader.QuotesChanged += depths =>
                {
                    //if (_depth2 == null && _sec2 != null)
                    //{

                        //if (_depth2 == null && _sec2 != null) 
                            _depth2 = depths.FirstOrDefault(d => d.Security == _sec2);
                        
                    //}
                };

                




                string short_long;

                string date = DateTime.Now.ToString("yyyyMMdd"); //текущая дата
                int time = Convert.ToInt32(DateTime.Now.ToString("HHmmss"));   //текущая дата
                int lasttime = time; //время последней сделки
                DateTime curTime = DateTime.Now; ; // текущее время
                DateTime runTime = DateTime.Now; // время запуска системы, точка отсчета
                DateTime FinishTime = DateTime.Now.AddHours(23 - runTime.Hour).AddMinutes(59 - runTime.Minute).AddSeconds(-curTime.Second); // устанавливаем время 23:00

                int timeFrame = 1; // периодичность расчетов (минут)
                int NextTfMinutes = (int)(Math.Truncate((double)(runTime.Minute / timeFrame))) * timeFrame + timeFrame; //получаем след период. например 32 минуты для 5минтки след период 35
                DateTime NextTime = runTime.AddMinutes(NextTfMinutes - runTime.Minute).AddSeconds(-runTime.Second); // время следующей свечи по окончанию текущего часа



                short_long = "";
                string comment = "", HourOrder = "";
                decimal SummBuy = 0, SummSell = 0, HourPrice = 0, MaxBuyVol = 0, MaxSellVol = 0, MaxBuyPrice = 0, MaxSellPrice = 0;
                string Vector = "0";
                int VolMaxHour = 0;
                DateTime MaxTime = curTime;


                //while (curTime < FinishTime)
                //{
                //    while (curTime < NextTime)
                //    {
                Trader.StartExport(Trader.SecuritiesTable);
                foreach (var qoute in this.Trader.GetMarketDepth(_sec2))
                        {
                       //     if (Convert.ToString(qoute.OrderDirection) == "Sell") { if (qoute.Volume > MaxSellVol) { MaxSellVol = qoute.Volume; MaxSellPrice = qoute.Price; } }
                        //    if (Convert.ToString(qoute.OrderDirection) == "Buy") { if (qoute.Volume > MaxBuyVol) { MaxBuyVol = qoute.Volume; MaxBuyPrice = qoute.Price; } }

                            //if (qoute.Volume > VolMaxHour) // после тестирования убрать знак =
                            //{
                            //    VolMaxHour = (int)qoute.Volume;
                            //    HourPrice = qoute.Price;
                            //    HourOrder = Convert.ToString(qoute.OrderDirection);
                            //    MaxTime = DateTime.Now;
                            //    SummSell = 0; SummBuy = 0;
                                //foreach (var qoute2 in Trader.GetMarketDepth(_sec2))
                                //{
                                //    if (Convert.ToString(qoute2.OrderDirection) == "Sell") { SummSell += qoute2.Volume; }
                                //    if (Convert.ToString(qoute2.OrderDirection) == "Buy") { SummBuy += qoute2.Volume; }
                                //}
                                //if (VolMaxHour > VolsecCode) { 
                                //    Vector = Convert.ToString(Math.Round(SummSell / SummBuy, 2)); 
                                //    goto ExtraSendMessage; 
                                //}
                        //}


                        }
                        //Thread.Sleep(10000); //ждем 10 секунд
                        //curTime = DateTime.Now;
                //    }
                //    Vector = Convert.ToString(Math.Round(SummSell / SummBuy, 2));
                //    if (HourOrder == "Sell") short_long = "-1"; else short_long = "1";
                //    comment = "макс объем за период " + VolMaxHour + " в " + MaxTime;
                //    cmd.CommandText = "INSERT INTO `history_glass` (`seccode`,`date`,`time`,`short_long`,`price`,`vol`,`maxbuyvol`,`maxsellvol`,`maxbuyprice`,`maxsellprice`,`vector`,`comments`,`type`,`time_frame`) "
                //                        + "VALUES ('"
                //                        + secCode + "','"
                //                        + date + "','"
                //                        + NextTime.ToString("HHmmss") + "','"
                //                        + short_long + "','"
                //                        + Convert.ToString(HourPrice).Replace(',', '.') + "','"
                //                        + Convert.ToString(VolMaxHour) + "','"
                //                        + Convert.ToString(MaxBuyVol).Replace(',', '.') + "','"
                //                        + Convert.ToString(MaxSellVol).Replace(',', '.') + "','"
                //                        + Convert.ToString(MaxBuyPrice).Replace(',', '.') + "','"
                //                        + Convert.ToString(MaxSellPrice).Replace(',', '.') + "','"


                //                        + Vector.Replace(',', '.') + "','"  // вектор меняем , на . для записи в базу дробных чисел
                //                        + comment + "','"
                //                        + "glass" + "','"
                //                        + Convert.ToString(timeFrame)
                //                        + "')";
                //    // cmd.ExecuteNonQuery();

                //    NextTfMinutes = (int)(Math.Truncate((double)(curTime.Minute / timeFrame))) * timeFrame + timeFrame; //вычисляем минуты следующего периода
                //    NextTime = curTime.AddMinutes(NextTfMinutes - curTime.Minute).AddSeconds(-curTime.Second);  // добавляем TimeFrame и убираем возможную погрешность в минутах и секундах

                //ExtraSendMessage: // метка для экстренного вывода сигнала

                //    if (VolMaxHour > VolsecCode)
                //    {
                //        Console.WriteLine("Запись в базу сигналов{0} ... Следующая запись в {1}", curTime, NextTime);
                //        VolsecCode = (int)VolMaxHour;
                //        //Vector = Math.Round(SummSell/SummBuy, 2);

                //        if (HourOrder == "Sell") short_long = "-1"; else short_long = "1";
                //        comment = "Мегозаявка " + HourOrder + ", объем " + VolMaxHour + ". Всего на покупку " + SummBuy + ". Всего на продажу " + SummSell + ". Вектор " + Vector + "." + " =-O";
                //        cmd.CommandText = "INSERT INTO `signal_temp` (`seccode`,`date`,`time`,`signal`,`short_long`,`forces`,`price`,`comments`,`type`,`time_frame`,`sent`) "
                //                            + " VALUES ('"
                //                            + secCode + "','"
                //                            + date + "','"
                //                            + MaxTime.ToString("HHmmss") + "','"
                //                            + "glass" + "','"
                //                            + short_long + "','"
                //                            + "0" + "','"
                //                            + Convert.ToString(HourPrice).Replace(',', '.') + "','"
                //                            + comment + "','"
                //                            + "glass" + "','"
                //                            + "60" + "','" //пока ставим 60, так как сигналы приходят по 60 в подписке, потом можно поменять на timeFrame
                //                            + "0"
                //                            + "')";
                //        //  cmd.ExecuteNonQuery();
                //    }
                //    VolMaxHour = 0;
                //    MaxSellVol = 0;
                //    MaxBuyVol = 0;

                //}
        }

        

	}
}